﻿using UnityEngine;
using System.Collections;
using System.Net.Sockets;
using System.Threading;
using System.Net;

public class UdpSocket
{
    public delegate void UDPSocketDelegate(byte[] pbuf, int dwCount, string ip, ushort tmpPort);

    UDPSocketDelegate udpDelegate;
    IPEndPoint udpId;
    Socket socket;

    byte[] RecvData;

    Thread RecvThread;

    public bool BindSocket(ushort port, int bufferLength, UDPSocketDelegate tmpDelegate)
    {
        udpId = new IPEndPoint(IPAddress.Any, port);

        UDPConnect();
        udpDelegate = tmpDelegate;

        RecvData = new byte[bufferLength];

        if (RecvThread == null)
        {
            RecvThread = new Thread(RecvDataThread);
            RecvThread.Start();
        }

        return true;
    }

    public void UDPConnect()
    {
        socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
        socket.Bind(udpId);
    }
    bool isRunnding = true;
    private void RecvDataThread()
    {
        while (isRunnding)
        {
            if (socket == null || socket.Available < 1)
            {
                Thread.Sleep(100);
                continue;
            }

            lock (this)
            {
                IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);

                EndPoint remote = sender;

                int myCount = socket.ReceiveFrom(RecvData, ref remote);

                if (udpDelegate != null)
                {
                    udpDelegate(RecvData, myCount, remote.AddressFamily.ToString(), (ushort)sender.Port);

                }
            }
        }
    }

    public int SendData(string ip, byte[] data, ushort upPort)
    {
        IPEndPoint SendToIp = new IPEndPoint(IPAddress.Parse(ip), upPort);

        if (!socket.Connected)
        {
            UDPConnect();
        }

        int mySend = socket.SendTo(data, data.Length, SocketFlags.None, SendToIp);

        return mySend;
    }
}
